import re

from enum import Enum


class ReType(Enum):
    CAR_NUMBER = 'car_num'
    ID_CARD = 'id_card'
    BANK_CARD = 'bank_card'
    EMAIL = 'email'
    CHINESE_PASSPORTS = 'chinese_passports'
    PHONE = 'phone'
    IPV4 = 'ipv4'
    IPV6 = 'ipv6'
    PASSWORD = 'password'


class ReRecognize(Enum):
    """正则表达式识别模式枚举"""
    #新能源车牌6位
    CAR_NUMBER = '([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领])[A-HJ-NP-Z][A-HJ-NP-Z0-9]{4,6}([A-HJ-NP-Z0-9挂学警港澳])'
    ID_CARD = r'([1-9]\d{5})(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)(\d{3}[\dXx])'
    # 使用负向断言，排除前后是数字的情况
    BANK_CARD = r'(?<![0-9])(62\d{2}|4\d{3}|5[1-5]\d{2})\d{8,11}(\d{4})(?![a0-9])'
    # 修复邮箱正则表达式，改进匹配逻辑
    EMAIL = r'([A-Za-z0-9._%+-]{1,3})[A-Za-z0-9._%+-]+(@[A-Za-z0-9.-]+\.[A-Za-z]{2,})'
    CHINESE_PASSPORTS = r'(?![a-zA-Z])([EGDSP])\d{6}(\d{2})(?![0-9])'
    #使用负向断言，排除前后是数字的情况，如果前后是中文或者标点符号就可以匹配
    PHONE = r'(?<![0-9a-zA-Z])(1[3-9]\d)\d{5}(\d{3})(?![0-9])'
    IPV4 = r'((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.)(?:(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){2}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)'
    IPV6 = r'([0-9a-fA-F]{1,4}:)([0-9a-fA-F]{1,4}:)(?:[0-9a-fA-F]{1,4}:){5}([0-9a-fA-F]{1,4}(?![0-9a-fA-F]))'
    PASSWORD =  r'(密码|pwd|password|密钥|口令)(.{0,2})([a-zA-Z0-9@$!！\(\).\-+_。^%*?&#]{6,20})'


class ReDesensitize(Enum):
    CAR_NUMBER = r'\1*****\2'
    ID_CARD = r'\1*****\2'
    BANK_CARD = r'\1******\2'
    EMAIL = r'\1*********\2'
    CHINESE_PASSPORTS = r'\1*******\2'
    PHONE = r'\1******\2'
    IPV4 = r'\1***.***.\2'
    IPV6 = r'\1\2:****:****:****:****:\3'
    PASSWORD = r'\1\2******'

# re 替换方法
def replace_by_re_sub(text: str, re_type: ReType):
    try:
        text = re.sub(ReRecognize[re_type.name].value, ReDesensitize[re_type.name].value, text)
        # pattern = re.compile(ReRecognize[re_type.name].value)
        # text = pattern.sub(ReDesensitize[re_type.name].value, text)
    except Exception as e:
        print("正则表达式替换出错: ", e)
    return text

def re_anonymize_all(text: str):
    for re_type in ReType:
        text = replace_by_re_sub(text, re_type)
    return text

def re_anonymize(text: str, *any_enum: ReType):
    for re_type in ReType:
        if re_type in any_enum:
            text = replace_by_re_sub(text, re_type)
    return text


